#include <ncurses.h>
#include "Curses.h"
#include "Window.h"

Curses& Curses::instance() {
	static Curses c;
	return c;
}

Curses::Curses() {
	init();
}

void Curses::init() {
	WINDOW* scr = initscr();
	m_stdscr = new Window(scr);
	
	// Turn of buffering and echoing.
	cbreak();
	noecho();
	keypad(scr, true);
	
	// Hide the cursor.
	curs_set(0);
	
	if (m_hasColor = has_colors()) {
		start_color();
	}
	
	clear();
	
	setCurrentWindow(m_stdscr);
	pushWindow(m_stdscr);
}

void Curses::pushWindow(Window* window) {
	m_windowStack.push_back(window);
}

void Curses::popWindow() {
	// Never pop stdscr from the stack.
	if (m_windowStack.size() > 1) {
		m_windowStack.pop_back();
	}
}

void Curses::clearScreen() {
	clear();
}

// 
// Input and output functions following.
//
//
void Curses::print(int x, int y, const std::string& str) {
	print(m_stdscr, x, y, str);
}

void Curses::print(Window* win, int x, int y, const std::string& str) {
	mvwprintw(win->window(), y, x, str.c_str());
}

void Curses::putchar(Window* win, int x, int y, char character) {
	mvwaddch(win->window(), y, x, character);
}

void Curses::refresh() {
//	m_current->refresh();
	std::vector<Window *>::iterator i;
	for (i = m_windowStack.begin(); i != m_windowStack.end(); ++i) {
		(*i)->refresh();
	}
}

int Curses::getchar() {
	return wgetch(m_current->window());
}

void Curses::shutdown() {
	endwin();
}